﻿namespace Typps
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Text;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    [DataContract]
    public class Fade : BaseEffect, IStateManager
    {
        #region Fields

        private bool isTrackingViewStateValue;
        private StateBag viewStateValue;

        #endregion Fields

        #region Constructors

        public Fade()
        {
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// The duration of the effect in milliseconds. The default value is 1000.
        /// </summary>
        [DataMember(Name="duration"),
        DefaultValue(1000)]
        public double Duration
        {
            get { return (double)(ViewState["Duration"] ?? 1000d); }
            set { ViewState["Duration"] = value; }
        }

        /// <summary>
        /// Lets you define a function that is called after the effect 
        /// finishes, e.g., function (element,effect){/* ... */}.
        /// </summary>
        [DefaultValue(null),
        Browsable(false)]
        public override string Finish
        {
            get { return (string)(ViewState["Finish"] ?? null); }
            set { ViewState["Finish"] = value; }
        }

        /// <summary>
        /// Determines the number of frames per second of the animation. The default is 60.
        /// </summary>
        [DataMember(Name="fps"),
        DefaultValue(60)]
        public int FPS
        {
            get { return (int)(ViewState["FPS"] ?? 60); }
            set { ViewState["FPS"] = value; }
        }

        /// <summary>
        /// Start opacity value in % ( "100%" ) or integer value. The default value is 0.
        /// </summary>
        [DataMember(Name="from"),
        DefaultValue(typeof(Unit), "0")]
        public Unit From
        {
            get { return (Unit)(ViewState["From"] ?? new Unit(0)); }
            set { ViewState["From"] = value; }
        }

        public override string Name
        {
            get { return "Fade"; }
            internal set { }
        }

        /// <summary>
        /// Using AddParallelEffect causes all of the registered effects to run in parallel.
        /// In other words, the registered Effects run together.
        /// While using AddNextEffect causes all of the registered effects to run one after the other.
        /// In other words, as one effects finishes, the next registered effect will run and so on. 
        /// The default is AddParellelEffect (when using UseDefault dictated by the control using this effect). When having registered more than
        /// one effect, RunMode set on this individual Effect has priority. This means if you set the 
        /// runtime mode explicity other than UseDefault, it will have precedence over runtime mode set directly on
        /// the control. Set runtime on the control instead of here, if all your effects share the same
        /// runtime mode. 
        /// </summary>
        public override EffectRunMode RunMode
        {
            get { return (EffectRunMode)(ViewState["RunMode"] ?? EffectRunMode.UseDefault); }
            set { ViewState["RunMode"] = value; }
        }

        /// <summary>
        /// Lets you define a function that is called before the effect 
        /// begins, e.g., function (element,effect){/* ... */}.
        /// </summary>
        [DefaultValue(null),
        Browsable(false)]
        public override string Setup
        {
            get { return (string)(ViewState["Setup"] ?? null); }
            set { ViewState["Setup"] = value; }
        }

        /// <summary>
        /// End opacity value in in % ( "100%" ) or integer value. The default value is 100. 
        /// </summary>
        [DataMember(Name="to"),
        DefaultValue(typeof(Unit), "100")]
        public Unit To
        {
            get { return (Unit)(ViewState["To"] ?? new Unit(100)); }
            set { ViewState["To"] = value; }
        }

        /// <summary>
        /// Produces a toggle effect. The default value is false. 
        /// If the value is set to true, the restoreColor option is ignored. 
        /// </summary>
        [DataMember(Name="toggle"),
        DefaultValue(false)]
        public bool Toggle
        {
            get { return (bool)(ViewState["Toggle"] ?? false); }
            set { ViewState["Toggle"] = value; }
        }

        /// <summary>
        /// Determines the type of transition. The default is 'fifthTransition'.
        /// </summary>
        [DataMember(Name="transition"),
        DefaultValue(TransitionName.fifthTransition)]
        public TransitionName Transition
        {
            get { return (TransitionName)(ViewState["Transition"] ?? TransitionName.fifthTransition); }
            set { ViewState["Transition"] = value; }
        }

        bool IStateManager.IsTrackingViewState
        {
            get
            {
                return isTrackingViewStateValue;
            }
        }

        private StateBag ViewState
        {
            get
            {
                if (viewStateValue == null)
                {
                    viewStateValue = new StateBag(false);
                    if (isTrackingViewStateValue)
                    {
                        ((IStateManager)viewStateValue).TrackViewState();
                    }
                }
                return viewStateValue;
            }
        }

        #endregion Properties

        #region Methods

        void IStateManager.LoadViewState(object savedState)
        {
            this.LoadViewState(savedState);
        }

        object IStateManager.SaveViewState()
        {
            return this.SaveViewState();
        }

        void IStateManager.TrackViewState()
        {
            isTrackingViewStateValue = true;
            if (viewStateValue != null)
                ((IStateManager)viewStateValue).TrackViewState();
        }

        public override void SetDirty()
        {
            if (viewStateValue != null)
                viewStateValue.SetDirty(true);
        }

        internal void LoadViewState(object savedState)
        {
            object[] states = (object[])savedState;
            ((IStateManager)ViewState).LoadViewState(states[0]);
        }

        internal object SaveViewState()
        {
            object[] states = new object[1];
            states[0] = (viewStateValue != null) ? ((IStateManager)viewStateValue).SaveViewState() : null;
            return states;
        }

        #endregion Methods
    }
}